"""Task data models and core data structures."""

from enum import Enum
from dataclasses import dataclass
from typing import List, Optional
import json


class TaskStatus(Enum):
    """Task status enumeration."""
    TODO = "todo"
    DONE = "done" 
    SKIPPED = "skipped"


@dataclass
class Task:
    """Task data model."""
    id: int
    name: str
    status: TaskStatus
    
    def to_dict(self) -> dict:
        """Convert task to dictionary."""
        return {
            "id": self.id,
            "name": self.name,
            "status": self.status.value
        }
    
    @classmethod
    def from_dict(cls, data: dict) -> 'Task':
        """Create task from dictionary."""
        return cls(
            id=data["id"],
            name=data["name"], 
            status=TaskStatus(data["status"])
        )


class TaskManager:
    """Core task management class."""
    
    def __init__(self):
        self.tasks: List[Task] = []
        self.next_id: int = 1
        self.benchmark_id: Optional[int] = None
        self.completion_history: List[int] = []
    
    def add_task(self, name: str, status: TaskStatus = TaskStatus.TODO) -> Task:
        """Add a new task."""
        task = Task(id=self.next_id, name=name, status=status)
        self.tasks.append(task)
        self.next_id += 1
        return task
    
    def get_task_by_id(self, task_id: int) -> Optional[Task]:
        """Get task by ID."""
        for task in self.tasks:
            if task.id == task_id:
                return task
        return None
    
    def mark_done(self, task_id: int) -> bool:
        """Mark task as done."""
        task = self.get_task_by_id(task_id)
        if task and task.status != TaskStatus.DONE:
            task.status = TaskStatus.DONE
            self.completion_history.append(task_id)
            return True
        return False
    
    def mark_undo(self, task_id: int) -> bool:
        """Mark task as todo."""
        task = self.get_task_by_id(task_id)
        if task:
            task.status = TaskStatus.TODO
            if task_id in self.completion_history:
                self.completion_history.remove(task_id)
            return True
        return False
    
    def delete_task(self, task_id: int) -> bool:
        """Delete task by ID."""
        for i, task in enumerate(self.tasks):
            if task.id == task_id:
                del self.tasks[i]
                if task_id in self.completion_history:
                    self.completion_history.remove(task_id)
                return True
        return False
    
    def delete_all_tasks(self):
        """Delete all tasks."""
        self.tasks.clear()
        self.completion_history.clear()
        self.next_id = 1
        self.benchmark_id = None
    
    def get_next_todo_task(self) -> Optional[Task]:
        """Get the next todo task with smallest ID."""
        todo_tasks = [t for t in self.tasks if t.status == TaskStatus.TODO]
        if todo_tasks:
            return min(todo_tasks, key=lambda t: t.id)
        return None
    
    def set_benchmark(self, task_id: int) -> bool:
        """Set benchmark starting point."""
        if self.get_task_by_id(task_id):
            self.benchmark_id = task_id
            return True
        return False
    
    def get_completed_tasks_from_benchmark(self) -> List[Task]:
        """Get completed tasks from benchmark point."""
        if self.benchmark_id is None:
            return [t for t in self.tasks if t.status == TaskStatus.DONE]
        
        return [t for t in self.tasks 
                if t.status == TaskStatus.DONE and t.id >= self.benchmark_id]
    
    def get_skipped_tasks(self) -> List[Task]:
        """Get all skipped tasks."""
        return [t for t in self.tasks if t.status == TaskStatus.SKIPPED]
    
    def reverse_last_completion(self) -> bool:
        """Reverse the last completion action."""
        if self.completion_history:
            last_completed_id = self.completion_history[-1]
            return self.mark_undo(last_completed_id)
        return False